const LhzxHttpClient = require('./LhzxHttpClient');
const { currentConfig } = require('./config_test');

/**
 * 手机验证功能模块
 * 提供发送验证码和验证码验证功能
 */

class MobileVerification {
    constructor() {
        this.smsClient = new LhzxHttpClient();
        this.config = currentConfig.yunyx;
        
        // 验证码存储（生产环境建议使用Redis）
        this.verificationCodes = new Map();
        
        // 验证码配置
        this.codeConfig = {
            length: 6,              // 验证码长度
            expireTime: 5 * 60 * 1000, // 5分钟过期
            resendInterval: 60 * 1000   // 1分钟内不能重复发送
        };
    }

    /**
     * 发送验证码
     * @param {string} mobile - 手机号
     * @param {string} type - 验证码类型 (register/login/reset)
     * @returns {Promise<Object>} - 发送结果
     */
    async sendVerificationCode(mobile, type = 'verify') {
        try {
            // 验证手机号格式
            if (!this.validateMobile(mobile)) {
                return {
                    success: false,
                    code: 'INVALID_MOBILE',
                    message: '手机号格式不正确'
                };
            }

            // 检查发送频率限制
            const lastSendTime = this.getLastSendTime(mobile);
            if (lastSendTime && (Date.now() - lastSendTime) < this.codeConfig.resendInterval) {
                const remainingTime = Math.ceil((this.codeConfig.resendInterval - (Date.now() - lastSendTime)) / 1000);
                return {
                    success: false,
                    code: 'TOO_FREQUENT',
                    message: `请等待${remainingTime}秒后再试`
                };
            }

            // 生成验证码
            const verifyCode = this.generateVerificationCode();
            
            // 构造短信内容
            const content = this.buildSMSContent(verifyCode, type);
            
            // 配置短信参数
            const smsConfig = {
                siid: this.config.siid,
                user: this.config.user,
                secretKey: this.config.secretKey,
                mobile: mobile,
                content: content,
                extcode: this.config.extcode,
                url: this.config.apiUrl
            };

            console.log(`📱 发送验证码到 ${mobile}: ${verifyCode}`);
            
            // 发送短信
            const result = await this.smsClient.sendSMS(smsConfig);
            
            if (result.retCode === '0000') {
                // 存储验证码
                this.storeVerificationCode(mobile, verifyCode);
                
                return {
                    success: true,
                    code: 'SEND_SUCCESS',
                    message: '验证码发送成功',
                    transactionID: result.transactionID
                };
            } else {
                return {
                    success: false,
                    code: 'SEND_FAILED',
                    message: result.retMsg || '发送失败',
                    retCode: result.retCode
                };
            }

        } catch (error) {
            console.error('发送验证码异常:', error);
            return {
                success: false,
                code: 'SYSTEM_ERROR',
                message: '系统异常，请稍后重试'
            };
        }
    }

    /**
     * 验证验证码
     * @param {string} mobile - 手机号
     * @param {string} code - 用户输入的验证码
     * @returns {Object} - 验证结果
     */
    verifyCode(mobile, code) {
        try {
            const storedData = this.verificationCodes.get(mobile);
            
            if (!storedData) {
                return {
                    success: false,
                    code: 'CODE_NOT_FOUND',
                    message: '验证码不存在或已过期'
                };
            }

            // 检查是否过期
            if (Date.now() > storedData.expireTime) {
                this.verificationCodes.delete(mobile);
                return {
                    success: false,
                    code: 'CODE_EXPIRED',
                    message: '验证码已过期'
                };
            }

            // 验证码匹配
            if (storedData.code === code) {
                // 验证成功后删除验证码
                this.verificationCodes.delete(mobile);
                return {
                    success: true,
                    code: 'VERIFY_SUCCESS',
                    message: '验证成功'
                };
            } else {
                // 增加错误次数
                storedData.errorCount = (storedData.errorCount || 0) + 1;
                
                // 错误次数过多则删除验证码
                if (storedData.errorCount >= 3) {
                    this.verificationCodes.delete(mobile);
                    return {
                        success: false,
                        code: 'TOO_MANY_ERRORS',
                        message: '验证码错误次数过多，请重新获取'
                    };
                }

                return {
                    success: false,
                    code: 'CODE_MISMATCH',
                    message: `验证码错误，还可尝试${3 - storedData.errorCount}次`
                };
            }

        } catch (error) {
            console.error('验证码验证异常:', error);
            return {
                success: false,
                code: 'SYSTEM_ERROR',
                message: '系统异常，请稍后重试'
            };
        }
    }

    /**
     * 生成验证码
     * @returns {string} - 6位数字验证码
     */
    generateVerificationCode() {
        const min = Math.pow(10, this.codeConfig.length - 1);
        const max = Math.pow(10, this.codeConfig.length) - 1;
        return Math.floor(Math.random() * (max - min + 1) + min).toString();
    }

    /**
     * 构造短信内容
     * @param {string} code - 验证码
     * @param {string} type - 类型
     * @returns {string} - 短信内容
     */
    buildSMSContent(code, type) {
        const templates = {
            register: `${this.config.signature}欢迎注册！您的验证码是：${code}，请在5分钟内使用。`,
            login: `${this.config.signature}您正在登录，验证码：${code}，请在5分钟内使用。`,
            reset: `${this.config.signature}您正在重置密码，验证码：${code}，请在5分钟内使用。`,
            verify: `${this.config.signature}您的验证码是：${code}，请在5分钟内使用。如非本人操作，请忽略此短信。`
        };
        
        return templates[type] || templates.verify;
    }

    /**
     * 存储验证码
     * @param {string} mobile - 手机号
     * @param {string} code - 验证码
     */
    storeVerificationCode(mobile, code) {
        this.verificationCodes.set(mobile, {
            code: code,
            createTime: Date.now(),
            expireTime: Date.now() + this.codeConfig.expireTime,
            errorCount: 0
        });
    }

    /**
     * 获取上次发送时间
     * @param {string} mobile - 手机号
     * @returns {number|null} - 上次发送时间戳
     */
    getLastSendTime(mobile) {
        const storedData = this.verificationCodes.get(mobile);
        return storedData ? storedData.createTime : null;
    }

    /**
     * 验证手机号格式
     * @param {string} mobile - 手机号
     * @returns {boolean} - 是否有效
     */
    validateMobile(mobile) {
        const mobilePattern = /^1[3-9]\d{9}$/;
        return mobilePattern.test(mobile);
    }

    /**
     * 清理过期验证码
     */
    cleanExpiredCodes() {
        const now = Date.now();
        for (const [mobile, data] of this.verificationCodes.entries()) {
            if (now > data.expireTime) {
                this.verificationCodes.delete(mobile);
            }
        }
    }

    /**
     * 获取验证码剩余时间
     * @param {string} mobile - 手机号
     * @returns {number} - 剩余秒数
     */
    getRemainingTime(mobile) {
        const storedData = this.verificationCodes.get(mobile);
        if (!storedData) return 0;
        
        const remaining = Math.max(0, storedData.expireTime - Date.now());
        return Math.ceil(remaining / 1000);
    }
}

// 使用示例
async function demo() {
    console.log('=== 手机验证功能演示 ===\n');
    
    const verification = new MobileVerification();
    const testMobile = currentConfig.yunyx.testMobile;
    
    console.log('测试手机号:', testMobile);
    console.log();
    
    // 1. 发送验证码
    console.log('1. 发送注册验证码...');
    const sendResult = await verification.sendVerificationCode(testMobile, 'register');
    console.log('发送结果:', sendResult);
    console.log();
    
    if (sendResult.success) {
        // 2. 模拟用户输入错误验证码
        console.log('2. 测试错误验证码...');
        const wrongResult = verification.verifyCode(testMobile, '000000');
        console.log('验证结果:', wrongResult);
        console.log();
        
        // 3. 查看剩余时间
        console.log('3. 验证码剩余时间...');
        const remainingTime = verification.getRemainingTime(testMobile);
        console.log('剩余时间:', remainingTime, '秒');
        console.log();
        
        console.log('💡 请查看手机短信，然后手动验证正确的验证码');
    }
}

// 定时清理过期验证码
const verification = new MobileVerification();
setInterval(() => {
    verification.cleanExpiredCodes();
}, 60000); // 每分钟清理一次

// 导出
module.exports = {
    MobileVerification,
    demo
};

// 如果直接运行此文件，则执行演示
if (require.main === module) {
    demo().catch(console.error);
} 